package com.internetCafes.spms.web.tenant.service.impl;

import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.core.generic.GenericDao;
import com.internetCafes.spms.core.generic.GenericServiceImpl;
import com.internetCafes.spms.core.model.pageModel.DataGrid;
import com.internetCafes.spms.web.certificate.entity.EmployeeInfo;
import com.internetCafes.spms.web.certificate.service.EmployeeInfoService;
import com.internetCafes.spms.web.sys.form.SysRegisterForm;
import com.internetCafes.spms.web.sys.model.ConfInfo;
import com.internetCafes.spms.web.sys.model.ResourceInfo;
import com.internetCafes.spms.web.sys.model.RoleInfo;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.internetCafes.spms.web.sys.service.*;
import com.internetCafes.spms.web.tenant.dao.TenantInfoMapper;
import com.internetCafes.spms.web.tenant.model.*;
import com.internetCafes.spms.web.tenant.service.*;
import com.internetCafes.spms.web.tenant.vo.TenantCertiInfoVo;
import com.internetCafes.spms.web.tenant.vo.TenantInfoVo;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 租户信息表 TenantInfoService 实现类
 *
 * @author Sunny
 * @email rekeeper2011@hotmail.com
 * @date 2019-10-31 18:09:54
 */
@Service("tenantInfoService")
public class TenantInfoServiceImpl extends GenericServiceImpl<TenantInfo, Long> implements TenantInfoService {

    @Autowired
    private TenantInfoMapper tenantInfoMapper;

    @Autowired
    private TenantDeptInfoService tenantDeptInfoService;

    @Autowired
    private TenantRoleInfoService tenantRoleInfoService;

    @Autowired
    private TenantRoleMenuInfoService tenantRoleMenuInfoService;

    @Autowired
    private UserInfoService userInfoService;

    @Autowired
    private ConfInfoService confInfoService;

    @Autowired
    private RoleMenuInfoService roleMenuInfoService;

    @Autowired
    private EmployeeInfoService employeeInfoService;

    @Autowired
    private RoleInfoService roleInfoService;

    @Autowired
    private ResourceInfoService resourceInfoService;

    @Autowired
    private TenantCertiInfoService tenantCertiInfoService;

    @Value("${system.upload.pic}")
    private String picPath;


    /**
     * 获取需要短信提醒的企业id
     *
     * @return 企业信息列表
     * @author Zj
     */
    @Override
    public List<Long> getTenantsOfExpireNotice() {
        return tenantInfoMapper.getTenantsOfExpireNotice();
    }

    @Override
    public List<TenantInfo> query(Map<String, Object> params) {
        return tenantInfoMapper.selectByParams(params);
    }

    @Override
    public TenantInfo findById(Long id) {
        return tenantInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<TenantInfo> queryByIds(List<Long> ids) {
        Map<String, Object> params = new HashMap<>();
        params.put("ids", ids);
        return tenantInfoMapper.selectByParams(params);
    }

    @Override
    public List<TenantInfo> page(Map<String, Object> params, int page, int rows) {
        params.put("page", page);
        params.put("rows", rows);
        return tenantInfoMapper.selectByParams(params);
    }

    @Override
    public long count(Map<String, Object> params) {
        return tenantInfoMapper.countByParams(params);
    }

    @Override
    public TenantInfo findFirst(Map<String, Object> params) {
        List<TenantInfo> list = tenantInfoMapper.selectByParams(params);
        TenantInfo tenantInfo = null;
        if (list != null && list.size() > 0) {
            tenantInfo = list.get(0);
        }
        return tenantInfo;
    }

    @Override
    public int save(TenantInfo tenantInfo) {
        return tenantInfoMapper.insert(tenantInfo);
    }

    @Override
    public int saveBatch(List<TenantInfo> tenantInfoList) {
        return tenantInfoMapper.insertBatch(tenantInfoList);
    }

    @Override
    public int saveSelective(TenantInfo tenantInfo) {
        return tenantInfoMapper.insertSelective(tenantInfo);
    }

    @Override
    public int update(TenantInfo tenantInfo) {
        return tenantInfoMapper.updateByPrimaryKey(tenantInfo);
    }


    @Override
    @Transactional
    public int update(TenantInfoVo t, boolean isEdit) {

        TenantInfo tenantInfo = findById(t.getTenantId());
        tenantInfo.setBusinessEntity(t.getBusinessEntity());
        tenantInfo.setBusinessEntityMobile(t.getBusinessEntityMobile());
        tenantInfo.setAddress(t.getAddress());
        tenantInfo.setRegion(t.getRegion());
        tenantInfo.setRegisteredCapital(t.getRegisteredCapital());
        tenantInfo.setStatus(ObjectUtil.isNull(t.getStatus()) ? CommonConstants.CommonStatus.ENABLE : t.getStatus());
        update(tenantInfo);

        saveResourceInfo(CommonConstants.ResourceInfo_PIC_Org_Certificate, t.getTenantId(), t.getCertiPic());

        if (CollectionUtils.isNotEmpty(t.getCertiInfos())) {
            saveOrgCertiInfo(t.getCertiInfos(), t, null);
        }

        if (StringUtils.isBlank(t.getCode()) || !isEdit) {
            return 0;
        }

        TenantDeptInfo d;
        Map<String, Object> params = new HashMap<>();
        params.put("deptName", "行政部");
        List<TenantDeptInfo> tenantDeptInfoList = tenantDeptInfoService.query(params);
        if (CollectionUtils.isNotEmpty(tenantDeptInfoList)) {
            d = tenantDeptInfoList.get(0);
        } else {
            throw new RRException("初始化部门错误，请联系管理员");
        }

        params = new HashMap<>();
        params.put("type", CommonConstants.CONF_Tenant_Admin_Role_Type);
        List<ConfInfo> confInfoList = confInfoService.query(params);
        ConfInfo c;
        if (confInfoList != null && confInfoList.size() > 0) {
            c = confInfoList.get(0);
        } else {
            throw new RRException("用户初始化错误，请联系管理员");
        }

        RoleInfo roleInfo = roleInfoService.queryObject(Long.parseLong(c.getValue()));
        if (roleInfo == null) {
            throw new RRException("用户角色信息初始化错误，请联系管理员");
        }

        // 创建角色
        TenantRoleInfo _roleInfo = new TenantRoleInfo();
        BeanUtils.copyProperties(roleInfo, _roleInfo);
        _roleInfo.setTenantId(t.getTenantId());
        _roleInfo.setCreateTime(new Date());
        tenantRoleInfoService.save(_roleInfo);

        List<Long> menuIdList = roleMenuInfoService.queryMenuIdList(roleInfo.getId());
        if (menuIdList != null && menuIdList.size() > 0) {
            menuIdList.forEach(id -> tenantRoleMenuInfoService.save(new TenantRoleMenuInfo(t.getTenantId(), roleInfo.getId(), id)));
        }

        EmployeeInfo e = new EmployeeInfo(CommonConstants.EmployeeInfoType.TENANT_ADMIN, t.getTenantId(), d.getId(), t.getBusinessEntity(), t.getBusinessEntityMobile());
        e.setStatus(CommonConstants.CommonStatus.ENABLE);
        employeeInfoService.save(e);

        UserInfo u = new UserInfo(t.getBusinessEntityMobile(), t.getBusinessEntity(),
                t.getPassword(), t.getBusinessEntityMobile(), t.getTenantId(), tenantInfo.getTenantName(),
                CommonConstants.UserInfoType.TENANT_ADMIN, e.getId());
        u.setTenantId(t.getTenantId());
        u.getRoleIdList().add(roleInfo.getId());
        u.setStatus(CommonConstants.CommonStatus.ENABLE);
        userInfoService.save(u);

        return 0;
    }


    private void saveResourceInfo(String moduleCode, Long moduleId, String picsStr) {
        Map<String, Object> params;
        if (picsStr != null) {
            params = new HashMap<>();
            params.put("moduleCode", moduleCode);
            params.put("moduleId", moduleId);
            resourceInfoService.deleteByModuleAndUserId(params);
        }
        if (StringUtils.isNotBlank(picsStr)) {
            ResourceInfo r = new ResourceInfo(moduleId, moduleCode, moduleId, "pic" + File.separator + picsStr);
            resourceInfoService.save(r);
        }
    }


    /**
     * 保存OrgCertiInfo
     *
     * @param tenantCertiInfoVos
     * @param t
     * @param otherQualificationGrade
     */
    private void saveOrgCertiInfo(List<TenantCertiInfoVo> tenantCertiInfoVos, TenantInfoVo t, String otherQualificationGrade) {
        Map<String, Object> params = new HashMap<>();
        params.put("userId", t.getTenantId());
        params.put("moduleId", t.getTenantId());
        params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Certificate);
        List<ResourceInfo> resourceInfoList = resourceInfoService.query(params);
        if (CollectionUtils.isNotEmpty(resourceInfoList)) {
            resourceInfoList.forEach((r) -> {
                Map<String, Object> _params = new HashMap<>();
                _params.put("tenantId", t.getTenantId());
                _params.put("resourceId", r.getId());
                tenantCertiInfoService.deleteByResourceAndTenantId(_params);
                resourceInfoService.delete(r.getId());
            });
        }

        ConfInfo c;
        ResourceInfo r;
        Map<String, String> confInfoMap;
        for (TenantCertiInfoVo vo : tenantCertiInfoVos) {
            r = new ResourceInfo(t.getTenantId(), CommonConstants.ResourceInfo_PIC_Certificate, t.getTenantId(), "pic" + File.separator + vo.getCertiPic());
            r.setResourceName(vo.getCertiName());
            r.setResourceCode(vo.getCertiCode());
            r.setReleaseDeptName(vo.getReleaseDeptName());
            r.setReleaseTime(vo.getReleaseTime());
            r.setValidityEndTime(vo.getValidityEndTime());
            resourceInfoService.save(r);

            confInfoMap = new HashMap<>();
            String[] certiItemIds = vo.getCertiItemIds().split(",");
            String[] certiItemNames = vo.getCertiItemNames().split(",");
            for (int i = 0; i < certiItemIds.length; i++) {
                String certiItemId = certiItemIds[i];
                if (certiItemId.indexOf("_") > 0) {
                    certiItemId = certiItemId.split("_")[0];
                }

                if (!confInfoMap.containsKey(certiItemId)) {
                    /*c = confInfoService.findById(confId);
                    if(StringUtils.isNotBlank(c.getCode()) && c.getCode().equals("other") && StringUtils.isNotBlank(otherQualificationGrade)){
                        if(otherQualificationGrade.indexOf(",") > -1){
                            for(String grade:otherQualificationGrade.split(",")){
                                tenantCertiInfoService.save(new TenantCertiInfo(t.getTenantId(), r.getId(), c.getId(), grade, ShiroUtils.getUserId()));
                            }
                        } else {
                            tenantCertiInfoService.save(new TenantCertiInfo(t.getTenantId(), r.getId(), c.getId(), otherQualificationGrade, ShiroUtils.getUserId()));
                        }
                    } else {*/
                    tenantCertiInfoService.save(new TenantCertiInfo(t.getTenantId(), r.getId(), certiItemIds[i], certiItemNames[i], ShiroUtils.getUserId()));
                    confInfoMap.put(certiItemId, certiItemId);
                    /*}*/
                }
            }
        }
    }


    @Override
    public int updateSelective(TenantInfo tenantInfo) {
        return tenantInfoMapper.updateByPrimaryKeySelective(tenantInfo);
    }

    @Override
    public int delete(Long id) {
        return tenantInfoMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int deleteBatch(List<Long> ids) {
        return tenantInfoMapper.deleteBatchByPrimaryKey(ids);
    }

    @Override
    public void deleteBatch(Long[] ids) {
        if (ids != null && ids.length > 0) {
            for (Long id : ids) {
                delete(id);
            }
        }
    }

    @Override
    public GenericDao<TenantInfo, Long> getDao() {
        return tenantInfoMapper;
    }

    /**
     * DataGrid
     */
    @Override
    public DataGrid dataGrid(Map<String, Object> params, int pageNo, int pageSize) {

        List<TenantInfo> tenantInfoList = page(params, (pageNo - 1 < 0 ? -1 : pageNo - 1) * pageSize, pageSize);
        long count = count(params);

        return new DataGrid(tenantInfoList, count, pageSize, pageNo);
    }

    @Override
    @Transactional
    public void save(SysRegisterForm r) {
        TenantInfo t = new TenantInfo(r.getOrgName(), r.getCertificateCode(), r.getContact(), r.getMobile());
        t.setStatus(CommonConstants.CommonStatus.DISABLE);
        tenantInfoMapper.insert(t);

        // 创建部门，默认的无效部门
        TenantDeptInfo d = new TenantDeptInfo(t.getTenantId(), "行政部", 0L, CommonConstants.CommonStatus.DISABLE, 0, CommonConstants.CommonStatus.DISABLE);
        tenantDeptInfoService.save(d);

        Map<String, Object> params = new HashMap<>();
        params.put("type", CommonConstants.CONF_Tenant_Contact_Role_Type);
        List<ConfInfo> confInfoList = confInfoService.query(params);
        ConfInfo c;
        if (confInfoList != null && confInfoList.size() > 0) {
            c = confInfoList.get(0);
        } else {
            throw new RRException("用户初始化错误，请联系管理员");
        }

        RoleInfo roleInfo = roleInfoService.queryObject(Long.parseLong(c.getValue()));
        if (roleInfo == null) {
            throw new RRException("用户角色信息初始化错误，请联系管理员");
        }

        // 创建角色
        TenantRoleInfo _roleInfo = new TenantRoleInfo();
        BeanUtils.copyProperties(roleInfo, _roleInfo);
        _roleInfo.setTenantId(t.getTenantId());
        _roleInfo.setRoleId(roleInfo.getId());
        _roleInfo.setCreateTime(new Date());
        tenantRoleInfoService.save(_roleInfo);

        List<Long> menuIdList = roleMenuInfoService.queryMenuIdList(roleInfo.getId());
        if (menuIdList != null && menuIdList.size() > 0) {
            menuIdList.forEach(id -> tenantRoleMenuInfoService.save(new TenantRoleMenuInfo(t.getTenantId(), roleInfo.getId(), id)));
        }

        EmployeeInfo e = new EmployeeInfo(CommonConstants.EmployeeInfoType.TENANT_CONTANT, t.getTenantId(), d.getId(), r.getContact(), r.getMobile());
        e.setStatus(CommonConstants.CommonStatus.ENABLE);
        employeeInfoService.save(e);

        UserInfo u = new UserInfo(r.getMobile(), r.getContact(), r.getPassword(), r.getMobile(), t.getTenantId(), t.getTenantName(), CommonConstants.UserInfoType.TENANT_ADMIN, e.getId());
        u.setTenantId(t.getTenantId());
        u.getRoleIdList().add(roleInfo.getId());
        if (r.isAuth()) {
            u.setStatus(CommonConstants.CommonStatus.ENABLE);
        } else {
            u.setStatus(CommonConstants.CommonStatus.DISABLE);
        }
        userInfoService.save(u);
    }
}
